"""AI服务提供商基类 - 消除代码重复."""

from __future__ import annotations

from abc import ABC, abstractmethod
from typing import Any
import requests
import logging

logger = logging.getLogger(__name__)


class AIProviderBase(ABC):
    """AI服务提供商抽象基类.

    统一不同AI服务商(通义千问、混元等)的调用接口，
    消除重复代码，提供统一的错误处理和重试逻辑。
    """

    def __init__(self, api_key: str, timeout: int = 30):
        """初始化AI服务提供商.

        Args:
            api_key: API密钥
            timeout: 请求超时时间(秒)
        """
        self.api_key = api_key
        self.timeout = timeout

    @abstractmethod
    def _build_request_config(self, prompt: str, **kwargs: Any) -> dict[str, Any]:
        """构建API请求配置(子类实现).

        Args:
            prompt: 输入提示词
            **kwargs: 额外参数(如max_tokens, temperature等)

        Returns:
            包含url, headers, payload的字典
        """
        pass

    @abstractmethod
    def _parse_response(self, response_json: dict[str, Any]) -> dict[str, Any]:
        """解析API响应(子类实现).

        Args:
            response_json: API返回的JSON数据

        Returns:
            标准化的响应数据
        """
        pass

    def call_api(
        self, prompt: str, max_tokens: int = 500, temperature: float = 0.7, **kwargs: Any
    ) -> dict[str, Any]:
        """统一的API调用接口.

        Args:
            prompt: 输入提示词
            max_tokens: 最大生成token数
            temperature: 生成温度
            **kwargs: 其他参数

        Returns:
            解析后的响应数据

        Raises:
            requests.RequestException: 网络请求失败
            ValueError: 响应解析失败
        """
        # 构建请求配置
        config = self._build_request_config(
            prompt, max_tokens=max_tokens, temperature=temperature, **kwargs
        )

        try:
            # 发送请求
            response = requests.post(
                config["url"],
                headers=config["headers"],
                json=config["payload"],
                timeout=self.timeout,
            )
            response.raise_for_status()

            # 解析响应
            response_json = response.json()
            return self._parse_response(response_json)

        except requests.Timeout:
            logger.error(f"{self.__class__.__name__} API调用超时")
            raise
        except requests.RequestException as e:
            logger.error(f"{self.__class__.__name__} API调用失败: {e}")
            raise
        except (KeyError, ValueError) as e:
            logger.error(f"{self.__class__.__name__} 响应解析失败: {e}")
            raise ValueError(f"AI服务响应格式错误: {e}")


class QwenProvider(AIProviderBase):
    """通义千问API实现."""

    def _build_request_config(self, prompt: str, **kwargs: Any) -> dict[str, Any]:
        """构建通义千问API请求配置."""
        return {
            "url": "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation",
            "headers": {
                "Authorization": f"Bearer {self.api_key}",
                "Content-Type": "application/json",
            },
            "payload": {
                "model": kwargs.get("model", "qwen-turbo"),
                "input": {"messages": [{"role": "user", "content": prompt}]},
                "parameters": {
                    "max_tokens": kwargs.get("max_tokens", 500),
                    "temperature": kwargs.get("temperature", 0.7),
                },
            },
        }

    def _parse_response(self, response_json: dict[str, Any]) -> dict[str, Any]:
        """解析通义千问API响应."""
        try:
            output = response_json["output"]
            text = output["choices"][0]["message"]["content"]
            return {
                "text": text,
                "finish_reason": output.get("finish_reason"),
                "usage": response_json.get("usage", {}),
            }
        except (KeyError, IndexError) as e:
            raise ValueError(f"通义千问响应格式错误: {e}")


class HunyuanProvider(AIProviderBase):
    """腾讯混元AI实现."""

    def __init__(self, api_key: str, secret_id: str = "", timeout: int = 30):
        """初始化混元AI.

        Args:
            api_key: API密钥
            secret_id: Secret ID(如果需要)
            timeout: 超时时间
        """
        super().__init__(api_key, timeout)
        self.secret_id = secret_id

    def _build_request_config(self, prompt: str, **kwargs: Any) -> dict[str, Any]:
        """构建混元AI请求配置."""
        return {
            "url": "https://hunyuan.tencentcloudapi.com/",
            "headers": {
                "Authorization": f"Bearer {self.api_key}",
                "Content-Type": "application/json",
            },
            "payload": {
                "Model": kwargs.get("model", "hunyuan-lite"),
                "Messages": [{"Role": "user", "Content": prompt}],
                "MaxTokens": kwargs.get("max_tokens", 500),
                "Temperature": kwargs.get("temperature", 0.7),
            },
        }

    def _parse_response(self, response_json: dict[str, Any]) -> dict[str, Any]:
        """解析混元AI响应."""
        try:
            choices = response_json["Response"]["Choices"]
            text = choices[0]["Message"]["Content"]
            return {
                "text": text,
                "finish_reason": choices[0].get("FinishReason"),
                "usage": response_json["Response"].get("Usage", {}),
            }
        except (KeyError, IndexError) as e:
            raise ValueError(f"混元AI响应格式错误: {e}")


# 工厂函数（可选）
def create_ai_provider(provider: str, api_key: str, **kwargs: Any) -> AIProviderBase:
    """创建AI服务提供商实例.

    Args:
        provider: 提供商名称("qwen" 或 "hunyuan")
        api_key: API密钥
        **kwargs: 额外参数

    Returns:
        AIProviderBase实例

    Raises:
        ValueError: 不支持的提供商
    """
    providers = {
        "qwen": QwenProvider,
        "hunyuan": HunyuanProvider,
    }

    provider_class = providers.get(provider.lower())
    if not provider_class:
        raise ValueError(f"不支持的AI提供商: {provider}")

    return provider_class(api_key, **kwargs)  # type: ignore[no-any-return]
